﻿//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//    Crolengi, this program (a part of program) is gameengine based on C++\Directx
//    Copyright (C) 2008 Pashinin Anton Alekseevich (Crol)
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//    (INCLUDING NEGLIGENCE OR OTHERWISE) 
//    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
//    EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//    Contacts: 
//    Mail: crolengi@gmail.com
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef  Render_Manager_h
#define  Render_Manager_h

#include <d3d9.h>
#include <d3dx9.h>

#include "..\\import\\CRLEngi_strings_lib\\CRLEngi_strings.h"
#include "..\\import\\param_trees_lib\\param_trees.h"

#include "include\\Utils\\Console.h"
#include "include\\Managers\\Camera_Manager.h"
#include "include\\Managers\\Object_Manager.h"
#include "include\\Managers\\Light_Manager.h"

//#################################################################################################################
///// 
///// 
//#################################################################################################################
class CLREngi_Render_Manager{
public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////< открытые глобальные переменные>///////////////////////////////////////////
	LPDIRECT3DDEVICE9       g_pd3dDevice;         // Our rendering device
	unsigned int            ErrorsCount;          //Счетчик ошибок инициализации
	/////////////// менеджеры /////////////////////////////////////////////////////////
	CLREngi_Camera_Manager *Camera_Manager;
	CLREngi_Object_Manager *Object_Manager;
	CLREngi_Console        *Console;
	CLREngi_Event_Manager  *EventManager;
	CLREngi_Light_Manager  *Light_Manager;
	/////////////// цвета /////////////////////////////////////////////////////////////
	D3DCOLOR       BACK_RENDERER_COLOR;
	/////////////// шрифты ////////////////////////////////////////////////////////////
	LPD3DXFONT              Font8Verdana;         
	LPD3DXFONT              Font16Verdana;        
	LPD3DXFONT              Font6Kartika;	
	/////////////// текстуры разных цветов, нужны для раскраски спец объектов /////////
	LPDIRECT3DTEXTURE9     *RedTexture; 
	LPDIRECT3DTEXTURE9     *WhiteTexture; 
	LPDIRECT3DTEXTURE9     *BlueTexture; 
	LPDIRECT3DTEXTURE9     *YellowTexture; 
	/////////////// Параметры для шейдера Phong_Light_noShadow ////////////////////////
	ID3DXEffect       *PhongLnSEffect;
	/////////////////////////
	CRLEngi_string      buffer;
//#################################################################################################################
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///// 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void           Init(){
		ErrorsCount = 0;
		///////////////////////////////////////////////////////////             цветные текстуры
		WhiteTexture   = new LPDIRECT3DTEXTURE9();	
		RedTexture     = new LPDIRECT3DTEXTURE9();	
		BlueTexture    = new LPDIRECT3DTEXTURE9();	
		YellowTexture  = new LPDIRECT3DTEXTURE9();	
		if (FAILED(D3DXCreateTextureFromFile( g_pd3dDevice,  "textures\\_def\\white.bmp",  WhiteTexture)))
		   {
				ErrorsCount++;
				Console->AddText("missed: textures\\_def\\white.bmp",1);
		   }
		if (FAILED(D3DXCreateTextureFromFile( g_pd3dDevice,  "textures\\_def\\red.bmp",    RedTexture  )))
		    {
				ErrorsCount++;
				Console->AddText("missed: textures\\_def\\red.bmp",1); 
			}
		if (FAILED(D3DXCreateTextureFromFile( g_pd3dDevice,  "textures\\_def\\Blue.bmp",   BlueTexture )))
			{
				ErrorsCount++;
				Console->AddText("missed: textures\\_def\\Blue.bmp",1); 
			}

		if (FAILED(D3DXCreateTextureFromFile( g_pd3dDevice,  "textures\\_def\\yellow.bmp",   YellowTexture )))
			{
				ErrorsCount++;
				Console->AddText("missed: textures\\_def\\yellow.bmp",1); 
			}		


		Init_Fonts();
		Init_PhongLnS();

		CRLEngi_string message;
		message = "Rendering manager inicialized with ";
		message += (int)ErrorsCount;
		message += " errors.";

		if(ErrorsCount)
		    Console->AddText(message,1); 
		else
			Console->AddText(message,3);  
	
	}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///// 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void           Init_Fonts(){

			HRESULT hr;
			HDC hDC;
			int nHeight;
			int nPointSize = 8;

			hDC = GetDC( NULL );

			nHeight = -( MulDiv( nPointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72 ) );

			ReleaseDC( NULL, hDC );

			if (FAILED(D3DXCreateFont( g_pd3dDevice, nHeight, 0, FW_BOLD, 0, FALSE, 
		                 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 
		                 DEFAULT_PITCH | FF_DONTCARE, TEXT("Verdana"), 
		                 &Font8Verdana )))
			{
			ErrorsCount ++;
			Console->AddText("failed: CreateFont Font8Verdana",1); 	
			}

			nPointSize = 16;
			nHeight = -( MulDiv( nPointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72 ) );
			if (FAILED(D3DXCreateFont( g_pd3dDevice, nHeight, 0, FW_BOLD, 0, FALSE, 
		                 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 
		                 DEFAULT_PITCH | FF_DONTCARE, TEXT("Verdana"), 
		                 &Font16Verdana )))	
			{
			ErrorsCount ++;
			Console->AddText("failed: CreateFont Font16Verdana",1); 	
			}

			if (FAILED(D3DXCreateFont( g_pd3dDevice, 14,0, FW_NORMAL, 0, FALSE, 
		                 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 
		                 DEFAULT_PITCH | FF_DONTCARE, TEXT("Kartika"), 
		                 &Font6Kartika )))	
			{
			ErrorsCount ++;
			Console->AddText("failed: CreateFont Font6Kartika",1); 	
			}
	
	
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///// 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void           Init_PhongLnS(){
		
		if (FAILED(D3DXCreateEffectFromFile(g_pd3dDevice, "fx\\ald_Phong.fx", NULL, NULL, 0, NULL, &PhongLnSEffect, NULL)))
			{
				ErrorsCount++;
				Console->AddText("missed:  fx\\ald_Phong.fx",1); 	
			}
	}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///// 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void           Setup_PhongLnS(){

		D3DXMATRIX matView;
	    D3DXMATRIX matProj;
		D3DXMATRIX nWorld;	
		matView = Camera_Manager->CurrientCamera->Camera->CamView;
		matProj = Camera_Manager->CurrientCamera->Camera->CamProjection;			
		g_pd3dDevice->GetTransform(D3DTS_WORLD,&nWorld);

		D3DXMATRIX mat_World_View_Proj = nWorld * matView * matProj;
		D3DXVECTOR4 ViewPos = D3DXVECTOR4(Camera_Manager->CurrientCamera->Camera->Position.x, 
										  Camera_Manager->CurrientCamera->Camera->Position.y,
										  Camera_Manager->CurrientCamera->Camera->Position.z, 
										  1.0f);

		//D3DXVECTOR4 LightPos   = D3DXVECTOR4(Light01_Position.x, Light01_Position.y, Light01_Position.z, 1.0f);
		//D3DXVECTOR4 LightColor = D3DXVECTOR4(1.6f, 1.6f, 1.2f, 1.0f);


		PhongLnSEffect->SetMatrix( "mat_World_View_Proj", &mat_World_View_Proj );
		PhongLnSEffect->SetMatrix( "matWorld", &nWorld );

		PhongLnSEffect->SetVector( "View_Pos", &ViewPos);
		//HDRIEffect->SetVector( "LightPos", &LightPos);

		//HDRIEffect->SetVector( "LightColor", &LightColor);

		PhongLnSEffect->SetFloat(  "LightFalloff", 1200.0f );
		PhongLnSEffect->SetFloat(  "LightSpecular", 8.5f );
		PhongLnSEffect->SetFloat(  "LightSpecular_Itens", 0.59f );
		PhongLnSEffect->SetFloat(  "LightAmbient", 0.01f );
		PhongLnSEffect->SetFloat(  "Attenuation", 0.8f );
		
		PhongLnSEffect->SetTechnique( "ald_Phong" );


	}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///// 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void           DrawText(CRLEngi_string text,int pos_x,int pos_y,int height){
		RECT destRect;
		SetRect( &destRect, pos_x, pos_y, 0, 0 );  
		Font8Verdana->DrawText( NULL,text.getChars(), -1, &destRect, DT_NOCLIP,D3DXCOLOR(1.4f, 1.4f,1.4f, 1.0f) );
}//void
void           DrawText(char *text,int pos_x,int pos_y,int height){
		CRLEngi_string text1;
        text1 = text;
		DrawText(text1,pos_x,pos_y,height);
}//void
void           DrawText(int text,int pos_x,int pos_y,int height){
		CRLEngi_string text1;
        text1 = text;
		DrawText(text1,pos_x,pos_y,height);
}//void
void           DrawText(float text,int pos_x,int pos_y,int height){
		CRLEngi_string text1;
        text1 = text;
		DrawText(text1,pos_x,pos_y,height);
}//void
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///// Отрисовка
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void           Render_Default(float FPSMSeconds,float elapsed){
		//////////////////////////////////////////////////////////////////////////////////////////////
		// Clear the backbuffer and the zbuffer
		g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 
		                           BACK_RENDERER_COLOR, 1.0f, 0 );
		//-------------------------------------------------------------
		// Начало отрисовки  сцены
		if( SUCCEEDED( g_pd3dDevice->BeginScene())){	
		
	//	g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
		if (!Console->visible)
			{				
				//CRLEngi_string buffer;
				buffer = "Текушая камера : ";
				buffer += (*Camera_Manager).GetCurrientIDint();
				   DrawText(buffer,5,5,5);
				buffer = "Число объектов : ";
				buffer += (int)(Object_Manager->LOADED_SIMPLE_objects);
				   DrawText(buffer,5,15,5);

				buffer = "Камера в : Position ";
				buffer += (int)(Camera_Manager->CurrientCamera->Camera->Position.x);
				buffer += " ";
				buffer += (int)(Camera_Manager->CurrientCamera->Camera->Position.y);
				buffer += " ";
				buffer += (int)(Camera_Manager->CurrientCamera->Camera->Position.z);
				buffer += "  Rotation ";
				buffer += (int)(Camera_Manager->CurrientCamera->Camera->Look.x);
				buffer += " ";
				buffer += (int)(Camera_Manager->CurrientCamera->Camera->Look.y);
				buffer += " ";
				buffer += (int)(Camera_Manager->CurrientCamera->Camera->Look.z);
				
				DrawText(buffer,5,25,5);

			    buffer = (int)(FPSMSeconds);

				buffer += " fps";

				FPS_CORRECTOR = (float)(FPSMSeconds / 200);
				if (FPS_CORRECTOR==0) FPS_CORRECTOR =1;
				
				DrawText(buffer,5,45,5);

				FPS_CORRECTOR = 1;

				
				Object_Manager->Render_Static(1);		
				Object_Manager->Render_Animated(1);
				Object_Manager->Render_PhysX(1);
				Object_Manager->Render_Interface(1);				


				Camera_Manager->SetupCurrientMatrix(&g_pd3dDevice);	

				//Console->Draw();
				   

			}else {

				buffer = (int)(FPSMSeconds);
				buffer += " fps";
				DrawText(buffer,9,2,5);
				g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );

				//Object_Manager->Render_All();				
					g_pd3dDevice->SetTexture(0,*WhiteTexture);			
				Camera_Manager->RenderAllCamera(&g_pd3dDevice);

					g_pd3dDevice->SetTexture(0,*RedTexture);
				Light_Manager->RenderAllLight(&g_pd3dDevice,WhiteTexture,YellowTexture);	



				Camera_Manager->SetupCurrientMatrix(&g_pd3dDevice);	
				g_pd3dDevice->SetTexture(0,*WhiteTexture);

				Console->Draw();

			}		


			g_pd3dDevice->EndScene();
		    }//~if( SUCCEEDED
		//---------------------------------------------------------------
		// Present the backbuffer contents to the display
		g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}//void

//#################################################################################################################
public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                     КОНСТРУКТОР
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CLREngi_Render_Manager(LPDIRECT3DDEVICE9       Device, 
		                   CLREngi_Camera_Manager *Cam_Manager,
		                   CLREngi_Object_Manager *Obj_Manager,
						   CLREngi_Light_Manager  *Lght_Manager,
		                   CLREngi_Console        *Cnsle){ 
    g_pd3dDevice   = Device;
	Camera_Manager = Cam_Manager;
	Object_Manager = Obj_Manager;
	Console        = Cnsle;
	Light_Manager = Lght_Manager;
		
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                       ДЕСТРУКТОР
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual ~CLREngi_Render_Manager(){	};

};
//#################################################################################################################
#endif 